package lt.ntec.danblog.server.blog.model.gae;

import lt.ntec.danblog.server.blog.model.Post;
import lt.ntec.danblog.server.blog.util.PostUtils;
import lt.ntec.danblog.server.core.Sys;
import lt.ntec.danblog.server.core.model.Comment;
import lt.ntec.danblog.server.core.model.Tag;
import lt.ntec.danblog.server.core.model.User;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.Text;
import com.google.inject.Inject;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.NotPersistent;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

@PersistenceCapable
class BlogPost implements Post {

    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key;
    @Persistent
    private Key jdoUser;
    private User author;
    @Persistent
    private String title;
    @Persistent
    private String urlString;
    @Persistent
    private Text content;
    @Persistent
    private Text preview;
    @Persistent
    private Date date;
    @Persistent
    private List<Key> tags = new ArrayList<Key>();
    @NotPersistent
    private Set<Tag> tagsLoaded = new TreeSet<Tag>();
    private ArrayList<BlogComment> comments = new ArrayList<BlogComment>();
    @Persistent
    private int voteDown = 0;
    @Persistent
    private int voteUp = 0;

    @Inject
    BlogPost(User author, String urlString) {
        this.author = author;
        this.urlString = urlString;
    }

    public Set<? extends Tag> getTags() {
        return tagsLoaded;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Long getId() {
        return key.getId();
    }

    public User getAuthor() {
        return author;
    }

    public String getContent() {
        return content.getValue();
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    @Override
    public void setContent(String content) {
        int length = Sys.getPreviewLength();
        this.content = new Text(content);
        this.preview = new Text(
                PostUtils.generatePreviewString(content, length));
    }

    @Override
    public List<BlogComment> getComments() {
        if (comments == null) {
            comments = new ArrayList<BlogComment>();
        }
        return comments;
    }

    @Override
    public void addComment(Comment comment) {
        if (comments == null) {
            comments = new ArrayList<BlogComment>();
        }
        this.comments.add((BlogComment) comment);

    }

    protected void setComment(List<BlogComment> comment) {
        this.comments = (ArrayList<BlogComment>) comment;
    }

    @Override
    public int getVoteUp() {
        return voteUp;
    }

    @Override
    public int getVoteDown() {
        return voteDown;
    }

    @Override
    public void addVoteDown() {
        voteDown++;
    }

    @Override
    public void addVoteUp() {
        voteUp++;
    }

    @Override
    public String getTagString() {
        StringBuffer buff = new StringBuffer();
        for (Tag tag : getTags()) {
            buff.append(tag.getValue() + " ");
        }
        if (buff.length() < 2) {
            return "";
        }
        return buff.substring(0, buff.length() - 1);
    }

    @SuppressWarnings("unchecked")
    @Override
    public void setTags(Set<? extends Tag> tagsNew) {
        this.tagsLoaded = (Set<Tag>) tagsNew;

    }

    @Override
    public String getPreview() {
        return preview.getValue();
    }

    @Override
    public String getUrlString() {
        return urlString;
    }

    @Override
    public boolean hasUserVoted(User user) {
        // TODO Auto-generated method stub
        return false;
    }

    public List<Key> getTagsKey() {
        return tags;
    }

    public void setTagsKeys(List<Key> tags) {
        this.tags = tags;
    }

    public Key getKey() {
        return key;
    }

    public Key getAuthorKey() {
        return jdoUser;
    }

    public void setAuthorKey(Key key) {
        this.jdoUser = key;
    }

    public void setAuthor(User author) {
        this.author = author;
    }
}
